from django.db import transaction
from django.db.models import Sum
from rest_framework import serializers
from rest_framework.exceptions import ValidationError

from financial_info.models import ReceiptModel, ReceiptItemModel


class ReceiptItemSerializer(serializers.ModelSerializer):
    """
    收款单中 收款项目 的序列化器
    """
    # 查询当前销售 出库单中已经 收金额
    already_receipt = serializers.SerializerMethodField(read_only=True, help_text='已经收款的金额')

    class Meta:
        model = ReceiptItemModel
        fields = '__all__'

    def get_already_receipt(self, obj: ReceiptItemModel):
        """
        查询当前 销售出库单中已经 收的货款金额
        :param obj: ReceiptItemModel
        :return: 0获取其他的数值
        """
        if obj.deliver_storage:
            sum_dict = ReceiptItemModel.objects.filter(deliver_storage_id=obj.deliver_storage.id)\
                .exclude(receipt__status='0')\
                .aggregate(sum=Sum('this_money'))
            if sum_dict:
                return sum_dict['sum'] if sum_dict['sum'] else 0
            return 0
        return 0


class ReceiptSerializer(serializers.ModelSerializer):
    """
    收款单——序列化器
    """
    item_list = ReceiptItemSerializer(many=True, required=False)

    class Meta:
        model = ReceiptModel
        fields = '__all__'

    def create(self, validated_data):
        if 'item_list' not in validated_data:
            return super(ReceiptSerializer, self).create(validated_data)
        item_list = validated_data.pop('item_list')
        with transaction.atomic():
            receipt = ReceiptModel.objects.create(**validated_data)
            for item in item_list:
                # 插入收款项目
                ReceiptItemModel.objects.create(receipt=receipt, **item)
        return receipt

    # 必须重写update
    def update(self, instance, validated_data):
        if instance.status != '0':
            raise ValidationError("收款单已经生效，不能修改!")
        with transaction.atomic():

            if 'item_list' in validated_data:
                item_list = validated_data.pop('item_list')
                old_list = instance.item_list.all()

                if old_list.exists():
                    # 然后把旧数据删除，因为在validated_data拿不到货品库存数据的ID
                    instance.item_list.all().delete()

                for item in item_list:  # 重新插入采购项 数据
                    ReceiptItemModel.objects.create(receipt=instance, **item)
            result = super(ReceiptSerializer, self).update(instance=instance, validated_data=validated_data)
        return result
